﻿using FytSoa.Common.Utils;
using FytSoa.Domain.Core.Result;
using Microsoft.AspNetCore.Http;
using Microsoft.AspNetCore.Mvc;
using Microsoft.Extensions.Hosting;

namespace FytSoa.Application.Sys;

[ApiExplorerSettings(GroupName = "v1")]
public class SysFileService:ISysFileService
{
    private readonly IHostingEnvironment _hostingEnvironment;
    private readonly ISysSafetyService _safetyService;
    public SysFileService(IHostingEnvironment hostingEnvironment
        , ISysSafetyService safetyService)
    {
        _hostingEnvironment = hostingEnvironment;
        _safetyService= safetyService;
    }
    
    /// <summary>
    /// 查询目录-树形结构
    /// </summary>
    /// <param name="path"></param>
    /// <returns></returns>
    public ApiResult<List<FileUtils.FileDirectory>> GetDirectory(string path)
    {
        if (string.IsNullOrEmpty(path))
        {
            path = _hostingEnvironment.ContentRootPath+"/upload/";
        }
        return JResult<List<FileUtils.FileDirectory>>.Success(FileUtils.GetFileDirectory(path));
    }

    /// <summary>
    /// 根据目录查询文件
    /// </summary>
    /// <param name="path"></param>
    /// <returns></returns>
    public ApiResult<List<FileUtils.ArrayFiles>> GetList(string path)
    {
        if (string.IsNullOrEmpty(path))
        {
            path = _hostingEnvironment.ContentRootPath+"/upload/";
        }
        return JResult<List<FileUtils.ArrayFiles>>.Success(FileUtils.GetDirs(path));
    }
    
    /// <summary>
    /// 根据目录查询文件
    /// </summary>
    /// <returns></returns>
    public ApiResult<List<FileUtils.FilesInfo>> GetFiles(string path)
    {
        var basePath = _hostingEnvironment.ContentRootPath;
        if (string.IsNullOrEmpty(path))
        {
            path = basePath + "/upload/";
        }
        else
        {
            path = basePath + path;
        }
        return JResult<List<FileUtils.FilesInfo>>.Success(FileUtils.ResolveFileInfo(path,basePath));
    }

    /// <summary>
    /// 上传文件
    /// </summary>
    /// <returns></returns>
    public async Task<ApiResult<SysFileDto>> Upload([FromForm]IFormFile file, string path)
    {
        var safety = _safetyService.Get();
        //原文件名
        var filename = file.FileName;
        //扩展名
        var fileExt = FileUtils.GetFileExt(filename);
        if (!string.IsNullOrEmpty(safety.Data.UploadBlack))
        {
            var arr = safety.Data.UploadBlack.Split(new char[] { '|' }, StringSplitOptions.RemoveEmptyEntries);
            if (arr.Contains(fileExt))
            {
                return JResult<SysFileDto>.Error("文件类型存在【上传黑名单】中，不允许上传~");
            }
        }
        if (!string.IsNullOrEmpty(safety.Data.UploadWhite))
        {
            var arr = safety.Data.UploadWhite.Split(new char[] { '|' }, StringSplitOptions.RemoveEmptyEntries);
            if (!arr.Contains(fileExt))
            {
                return JResult<SysFileDto>.Error("文件类型不存在【上传白名单】中，不允许上传~");
            }
        }
        //判断是否包含盘符： 文件名不允许包含冒号，如果存在，则使用新的文件名字
        if (filename.Contains(":"))
        {
            filename = DateTime.Now.GetTimeStamp() + "." + fileExt;
        }
        var basePath =_hostingEnvironment.ContentRootPath+path;
        FileUtils.CreateSuffic(basePath);
        await using (var stream = new FileStream(basePath + filename, FileMode.Create))
        {
            await file.CopyToAsync(stream);
            stream.Flush();
        }
        return JResult<SysFileDto>.Success(new SysFileDto()
        {
            path = path + filename,
            name = filename,
            size = Convert.ToInt64(Math.Round(Convert.ToDecimal(file.Length / 1024), 0))
        });
    }

    /// <summary>
    /// 删除文件
    /// </summary>
    /// <returns></returns>
    public ApiResult<bool> DeleteFile(string path)
    {
        var basePath =_hostingEnvironment.ContentRootPath+path;
        FileUtils.DeleteFile(basePath);
        return JResult<bool>.Success();
    }

    /// <summary>
    /// 删除目录及目录下文件
    /// </summary>
    /// <returns></returns>
    public ApiResult<bool> DeleteDirectory(string path)
    {
        var basePath =_hostingEnvironment.ContentRootPath+path;
        FileUtils.ClearDirectory(basePath);
        FileUtils.DeleteDirectory(basePath);
        return JResult<bool>.Success();
    }
}